﻿using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Appology.SugarSync.IO;
using Appology.SugarSync.IO.Primitives;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Tasks;
using System.Threading.Tasks;

namespace Appology.SugarSync.Explorer.Phone
{
    public partial class File : PhoneApplicationPage
    {
        private readonly DispatcherTimer _mediaTimer;
        
        public File()
        {
            InitializeComponent();
            DataContext = ApplicationState.Current.History.Pop();

            Refresh = (ApplicationBarIconButton) ApplicationBar.Buttons[0];
            Download = (ApplicationBarIconButton) ApplicationBar.Buttons[1];
            Share = (ApplicationBarIconButton)ApplicationBar.Buttons[2];
            Email = (ApplicationBarIconButton) ApplicationBar.Buttons[3];

            _mediaTimer = new DispatcherTimer();
            _mediaTimer.Interval = TimeSpan.FromSeconds(.5);
            _mediaTimer.Tick += _mediaTimer_Tick;

            ImageContainer.Visibility = System.Windows.Visibility.Collapsed;
            MediaContainer.Visibility = System.Windows.Visibility.Collapsed;

            PlayImage.Visibility = System.Windows.Visibility.Visible;
            PauseImage.Visibility = System.Windows.Visibility.Collapsed;

            RefreshFileInfo();
        }

        private void _mediaTimer_Tick(object sender, EventArgs e)
        {
            if(Media.NaturalDuration.HasTimeSpan)
            {
                var timeRemaining = Media.NaturalDuration.TimeSpan.Subtract(Media.Position);
                var timeElapsed = Media.Position;

                if (Media.NaturalDuration.TimeSpan.Hours > 0.00)
                {
                    TimeElapsed.Text = string.Format("{0:00}:{1:00}:{2:00}", timeElapsed.Hours, timeElapsed.Minutes, timeElapsed.Seconds);
                    TimeRemaining.Text = string.Format("-{0:00}:{1:00}:{2:00}", timeRemaining.Hours, timeRemaining.Minutes, timeRemaining.Seconds);
                }
                else if(Media.NaturalDuration.TimeSpan.Minutes > 0.00)
                {
                    TimeElapsed.Text = string.Format("{0:00}:{1:00}", timeElapsed.Minutes, timeElapsed.Seconds);
                    TimeRemaining.Text = string.Format("-{0:00}:{1:00}", timeRemaining.Minutes, timeRemaining.Seconds);
                }
                else
                {
                    TimeElapsed.Text = string.Format("0:{0:00}", timeElapsed.Seconds);
                    TimeRemaining.Text = string.Format("-0:{0:00}", timeRemaining.Seconds);
                }
                
                Position.Value = Media.Position.TotalMilliseconds;
            }
        }

        private async void RefreshFileInfo()
        {
            var pathInfo = (SugarSyncPathInfo) DataContext;

            await pathInfo.RefreshAsync();

            var fileInfo = (SugarSyncFileInfo)DataContext;

            if (fileInfo.IsPublicUriEnabled)
            {
                Share.IconUri = new Uri("/icons/appbar.stopshare.rest.png", UriKind.Relative);
                Email.IsEnabled = true;
            }
            else
            {
                Share.IconUri = new Uri("/icons/appbar.share.rest.png", UriKind.Relative);
                Email.IsEnabled = false;
            }

            PreparePreview();
        }

        private void Refresh_Click(object sender, EventArgs e)
        {
            RefreshFileInfo();
        }

        private async void Share_Click(object sender, EventArgs e)
        {
            var fileInfo = (SugarSyncFileInfo) DataContext;

            if (fileInfo.IsPublicUriEnabled)
            {
                await fileInfo.MakePrivate();
                await TaskEx.Delay(TimeSpan.FromSeconds(1));
                RefreshFileInfo();
            }
            else
            {
                await fileInfo.MakePublic();
                await TaskEx.Delay(TimeSpan.FromSeconds(1));
                RefreshFileInfo();
            }
        }

        private void Email_Click(object sender, EventArgs e)
        {
            var fileInfo = (SugarSyncFileInfo) DataContext;

            var emailComposeTask = new EmailComposeTask();
            emailComposeTask.Body = string.Format("\r\n\r\n{0}\r\n\r\nSent from Appology SugarSync Explorer for Windows Phone 7\r\nVisit us at http://www.appology.net", fileInfo.PublicUri);
            emailComposeTask.Subject = string.Format("Emailing {0}", fileInfo.Name);
            emailComposeTask.Show();
        }

        private void RenameFile_Click(object sender, EventArgs e)
        {
            ApplicationState.Current.History.Push((SugarSyncPathInfo) DataContext);
            NavigationService.Navigate(new Uri("/RenameFile.xaml", UriKind.Relative));
        }

        private async void DeleteFile_Click(object sender, EventArgs e)
        {
            var fileInfo = (SugarSyncFileInfo) DataContext;

            if (MessageBox.Show(string.Format("Delete \"{0}\"?", fileInfo.Name), "Are you sure?", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                await fileInfo.Delete();

                await TaskEx.Delay(TimeSpan.FromSeconds(1));

                NavigationService.GoBack();
            }
        }

        private void Media_MediaOpened(object sender, RoutedEventArgs e)
        {
            Rewind.IsEnabled = true;
            Forward.IsEnabled = true;

            Position.Maximum = Media.NaturalDuration.TimeSpan.TotalMilliseconds;
            Position.Minimum = 0.0;
        }

        private void Media_MediaEnded(object sender, RoutedEventArgs e)
        {
            // make play or pause = play...
        }

        private void Media_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            MessageBox.Show("Media failed to open.");
        }

        private void PlayOrPause_Click(object sender, RoutedEventArgs e)
        {
            if (Media.CurrentState == MediaElementState.Playing && Media.CanPause)
            {
                Media.Pause();
                PauseImage.Visibility = System.Windows.Visibility.Collapsed;
                PlayImage.Visibility = System.Windows.Visibility.Visible;
            }
            else if (Media.CurrentState == MediaElementState.Paused || Media.CurrentState == MediaElementState.Stopped || Media.CurrentState == MediaElementState.Opening)
            {
                Media.Play();
                PlayImage.Visibility = System.Windows.Visibility.Collapsed;
                PauseImage.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void Rewind_Click(object sender, RoutedEventArgs e)
        {
            if (!Media.CanSeek)
            {
                return;
            }

            if (Media.Position.TotalSeconds > 1.0)
            {
                Media.Position = Media.Position.Add(TimeSpan.FromSeconds(-1.0));
            }
            else
            {
                Media.Position = TimeSpan.FromSeconds(0);
            }
        }

        private void Forward_Click(object sender, RoutedEventArgs e)
        {
            if (!Media.CanSeek)
            {
                return;
            }

            if (!Media.NaturalDuration.HasTimeSpan)
            {
                return;
            }

            if (Media.Position.TotalSeconds < Media.NaturalDuration.TimeSpan.TotalSeconds - 2.0)
            {
                Media.Position = Media.Position.Add(TimeSpan.FromSeconds(1.0));
            }
            else
            {
                Media.Position = Media.NaturalDuration.TimeSpan;
            }
        }

        private async void PreparePreview()
        {
            if (Media.CurrentState != MediaElementState.Closed)
            {
                Media.Stop();
                Media.ClearValue(MediaElement.SourceProperty);
            }

            var fileInfo = (SugarSyncFileInfo)DataContext;

            if (fileInfo.ContentType == "image/jpeg")
            {
                using (var stream = await fileInfo.OpenPreviewImageAsync(400, 400, false, 0))
                {
                    Image.Visibility = System.Windows.Visibility.Visible;

                    var bitmapImage = new BitmapImage();
                    bitmapImage.SetSource(stream);
                    Image.Source = bitmapImage;
                }

                ImageContainer.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                ImageContainer.Visibility = System.Windows.Visibility.Collapsed;
            }

            if (fileInfo.ContentType == "audio/mp4")
            {
                fileInfo.IsBusy = true;

                IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication();

                if (isolatedStorageFile.FileExists(fileInfo.Name))
                {
                    fileInfo.IsBusy = true;

                    IsolatedStorageFileStream downloadedFile = isolatedStorageFile.OpenFile(fileInfo.Name, FileMode.Open);
                    Media.AutoPlay = false;
                    Media.SetSource(downloadedFile);
                    PlayOrPause.IsEnabled = true;
                    _mediaTimer.Start();

                    PauseImage.Visibility = System.Windows.Visibility.Collapsed;
                    PlayImage.Visibility = System.Windows.Visibility.Visible;

                    fileInfo.IsBusy = false;
                }

                MediaContainer.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                MediaContainer.Visibility = System.Windows.Visibility.Collapsed;
            }
        }

        private async void Download_Click(object sender, EventArgs e)
        {
            if(Media.CurrentState != MediaElementState.Closed)
            {
                Media.Stop();
                Media.ClearValue(MediaElement.SourceProperty);
            }

            var fileInfo = (SugarSyncFileInfo)DataContext;

            using (var stream = await fileInfo.OpenReadAsync())
            {
                using (IsolatedStorageFile isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    if (isolatedStorageFile.FileExists(fileInfo.Name))
                    {
                        isolatedStorageFile.DeleteFile(fileInfo.Name);
                    }

                    fileInfo.IsBusy = true;

                    using (IsolatedStorageFileStream tempFile = isolatedStorageFile.CreateFile(fileInfo.Name))
                    {
                        int bytesRead;
                        var buffer = new byte[65536];

                        do
                        {
                            bytesRead = stream.Read(buffer, 0, buffer.Length);
                            tempFile.Write(buffer, 0, bytesRead);
                            tempFile.Flush();
                        } while (bytesRead > 0);
                    }
                }
            }

            PreparePreview();
        }
    }
}